package copy_struct

import (
	"errors"
	"reflect"
)

func main() {

}

type AssignInterface[T any] interface {
	GetNilVal() T
}

var (
	ErrTypeNotEq = errors.New("合并参数类型需要一致")
)

// 关于零值可用与零值不可用的问题【默认零值不可用】
// 将desc合并到src中【支持复杂结构体】
// eg: src{a: 1, b: 2 } , desc{ b: 4, c: 5 } ==> { a: 1, b: 2, c: 5 }
//   - desc中存在，而src中不存在的
//     基本类型属性，会复制到src中。  （int，string，float，bool）
//     pointer、struct，会复制到src中。   （*User，User{}）
//     map，会复制到src中。   （map[int64]string，map[string]User{}，map[string]*User{}） - 仅仅支持单层，多层的自己合并再给我
//     slice array，会复制到src中。 （[]int{},[]User{}, []*User{}）
//   - desc中存在，src中存在的
//     以src的为主
//   - desc中不存在，src中存在
//   - desc中不存在，src中不存在
//     不处理
//
// - desc中存在，而src中也存在的 基本属性 ，会复制到src中
// - desc中存在，而src中不存在的
// - desc中存在，而src中也存在的 指针、结构体 ，会递归进入对应的指针结构体，随后将desc中属性复制到src中
func AssignStruct[T any](src, desc T) (res T, err error) {
	srcTyp, descTyp := reflect.TypeOf(src), reflect.TypeOf(desc)
	srcVal, descVal := reflect.ValueOf(src), reflect.ValueOf(desc)

	// 将地址全部转化得到实际的值
	for srcTyp.Kind() == reflect.Ptr {
		srcTyp = srcTyp.Elem()
		srcVal = srcVal.Elem()
	}
	for descTyp.Kind() == reflect.Ptr {
		descTyp = descTyp.Elem()
		descVal = descVal.Elem()
	}

	// 校验类型（struct与指针）-- 职能由泛型保证
	if srcTyp.Kind() != descTyp.Kind() {
		err = ErrTypeNotEq
		return
	}

	// 根据不同类型做不同处理
	switch {

	}
	return
}
